package Logica;

import Datatypes.Archivo;
import Datatypes.Base64;
import Datatypes.DataVersion;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.text.Normalizer;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.io.FileUtils;

public class FileManager {
    
    private String property = System.getProperty("user.dir");
    
    public FileManager(String dirServidor){
        
        this.property = dirServidor;
        
    }        
    
    public String getProperty(){return this.property;}
    
    public  void crearCarpetasJuego(String nombre_juego){

        String path = property + "/Data/Juegos/"+nombre_juego+"/imagen";
        String path2 = property + "/Data/Juegos/"+nombre_juego+"/versiones/aprobadas";
        String path3 = property + "/Data/Juegos/"+nombre_juego+"/versiones/pendientes";
        String path4 = property + "/Data/Juegos/"+nombre_juego+"/versiones/rechazadas";
        
        File dirImagen = new File(path);
        dirImagen.mkdirs();
        File dirVersiones_a = new File(path2);
        dirVersiones_a.mkdirs();
        File dirVersiones_p = new File(path3);
        dirVersiones_p.mkdirs();
        File dirVersiones_r = new File(path4);
        dirVersiones_r.mkdirs();
        
    }
    
    public  void borrarDirectorio(String directorio) throws Exception{
        
        if(directorio.contains(property)){ //control para que no se pueda borrar cosas fuera de la carpeta del programa
            
            File dir = new File(directorio);
            try {
                                
                FileUtils.cleanDirectory(dir);
                Files.delete(dir.toPath());
            
            }
            catch (IOException ex) {
                
                throw new Exception("Error al borrar la carpeta del juego: "+ex.getMessage());
            
            }
            
        }
        
    }
    public  int crearImagenJuego(FileItem imagen, String nombre_juego) throws Exception{
        
        String nom_imagen = normalizar(imagen.getName());
        String path = property + "/Data/Juegos/"+nombre_juego+"/imagen/"+nom_imagen;
        File img = new File(path);
        int retorno = -1;
        try{
            
            if(!img.exists()){
                
                imagen.write(img);
                retorno = 0;
                
            }
            else{
                
                throw new Exception("Archivo ya existente");
                
            }
            
        }
        catch(Exception ex) {
            
            throw new Exception("No se pudo crear la imagen: "+ex.getMessage());
                        
        }
        
        return retorno;
        
    }
    
    public void crearImagenJuego(byte[] imagen, String nombre_archivo, String nombre_juego) throws Exception{
        
        File img = new File(property+"/Data/Juegos/"+nombre_juego+"/imagen/"+nombre_archivo);
        try{
        
            FileOutputStream fos = new FileOutputStream(img);
            fos.write(imagen);
            fos.flush();
            fos.close();
        
        }
        catch(IOException e){
            
            throw new Exception("No se pudo crear la imagen: "+e.getMessage());
            
        }
    }
    
    public  DataVersion crearPendiente(FileItem version, String nombre_juego, String num_version) throws Exception{
        
        DataVersion dv = null;
        File archivo = null;
        num_version = num_version.replaceAll("\\.", "");        
        String nom_version = num_version+"-"+normalizar(version.getName());
        String path = property + "/Data/Juegos/"+nombre_juego+"/versiones/pendientes/"+nom_version;
        archivo = new File(path);
                
        try{
          
            if(!archivo.exists()){
                
                version.write(archivo);
                Double tamanio = (double)archivo.length()/1024;
                String[] pathcreado = path.split(property+"/");
                dv = new DataVersion(null, null, null, tamanio , null, null, pathcreado[1]);
                //public DataVersion(Double version, String nombreJuego,
                        //String nombreDesarrollador, Double tamanio, Integer codigoJuego, PDate fechaV, String archivo) {
            }
            else{

                throw new Exception("Archivo ya existente");

            }
        }
        catch(Exception e){
                
            throw new Exception("No se pudo crear el archivo: "+e.getMessage());
                
        }
        
        return dv;
        
    }
    
    public  DataVersion crearPendiente(byte[] version, String nombre_juego, String num_version, String nombre_archivo) throws Exception{
        DataVersion dv = null;
        File archivo = null;
        num_version = num_version.replaceAll("\\.", "");
        String path = property + "/Data/Juegos/"+nombre_juego+"/versiones/pendientes/"+num_version+"-"+nombre_archivo;
        archivo = new File(path);
        try{
            
            if(archivo.exists()){
                
                archivo.delete();
                
            }
                
            FileOutputStream fos = new FileOutputStream(archivo);
            fos.write(version);
            fos.flush();
            fos.close();
            double tamanio = archivo.length()/1024;
            String[] pathcreado = path.split(property+"/");
            dv = new DataVersion(null, null, null, tamanio , null, null, pathcreado[1]);

           
        }
        catch(IOException e){
            
            throw new Exception("No se pudo crear el archivo: "+e.getMessage());
            
        }
        
        return dv;
    }
    
    public void movetoAprobada(String path, String nombre_juego) throws Exception{
        
        
        File archivo = new File(path);
        String nuevo_path = property + "/Data/Juegos/"+nombre_juego+"/versiones/aprobadas/"+archivo.getName();
        
        try {
            
            Files.move(archivo.toPath(), new File(nuevo_path).toPath(), StandardCopyOption.REPLACE_EXISTING);
        
        }
        
        catch (IOException e) {
           
            throw new Exception("Error al mover a la carpeta aprobadas: "+e.getMessage());
            
        }
            
    }
    
    public  void movetoRechazada(String path, String nombre_juego) throws Exception{
        
        
        File archivo = new File(path);
        String nuevo_path = property + "/Data/Juegos/"+nombre_juego+"/versiones/rechazadas/"+archivo.getName();
        
        try {
            
            Files.move(archivo.toPath(), new File(nuevo_path).toPath(), StandardCopyOption.REPLACE_EXISTING);
        
        }
        
        catch (IOException e) {
           
            throw new Exception("Error al mover a la rechazadas: "+e.getMessage());
            
        }
            
    }
     
    public String pathNormalizador(String cadena){
        
        String normalizada = Normalizer.normalize(cadena, Normalizer.Form.NFD);
        normalizada = normalizada.replaceAll("[^\\p{ASCII}]", "");        
        normalizada = normalizada.replaceAll("\\s", "");    
        normalizada = normalizada.replaceAll("\\?", ""); 
        normalizada = normalizada.replaceAll("\\]\\-\\+\\^\\[\\*\\}\\{\\,\\;\\<\\>", "");
        normalizada = normalizada.replaceAll("'", "");
        normalizada = normalizada.replaceAll("\"", "");                
        String path = "Data/Juegos/"+normalizada+"/imagen/img.jpeg";       
        return path;
    }
    
    public String pathImagen(String nombrejuego, String nomArchivo){
        
        return "Data/Juegos/"+nombrejuego+"/imagen/"+nomArchivo;     
            
    }
    
    public String pathArchivo(String nombrejuego, String estado /*aprobada / rechazada*/, String nomArchivo){
        
        return "Data/Juegos/"+nombrejuego+"/versiones/"+estado+"/"+nomArchivo;
    
    }
    
    public String normalizarArchivo(String cadena){
        
        String normalizada = Normalizer.normalize(cadena, Normalizer.Form.NFD);
        normalizada = normalizada.replaceAll("[^\\p{ASCII}]", "");        
        normalizada = normalizada.replaceAll("\\s", "");    
        normalizada = normalizada.replaceAll("\\?", ""); 
        normalizada = normalizada.replaceAll("\\]\\-\\+\\^\\[\\*\\}\\{\\,\\;\\<\\>", "");
        normalizada = normalizada.replaceAll("'", "");
        normalizada = normalizada.replaceAll("\"", "");                
        String path = "Data/Juegos/"+normalizada+"/versiones/pendientes/10.jar";       
        return path;
    }
    
    public String normalizar(String cadena){
        
        String normalizada = Normalizer.normalize(cadena, Normalizer.Form.NFD);
        normalizada = normalizada.replaceAll("[^\\p{ASCII}]", "");        
        normalizada = normalizada.replaceAll("\\s", "");    
        normalizada = normalizada.replaceAll("\\?", ""); 
        normalizada = normalizada.replaceAll("\\]\\-\\+\\^\\[\\*\\}\\{\\.\\,\\;\\<\\>", "");
        normalizada = normalizada.replaceAll("'", "");
        normalizada = normalizada.replaceAll("\"", "");                
        return normalizada;
    }
    
    public void crearArchivosDePrueba(String nombreJuego) throws Exception{
        
        crearCarpetasJuego(nombreJuego);
        String origen = property+"/Data/install/10.jar";
        String destino = property + "/Data/Juegos/"+nombreJuego+"/versiones/pendientes/10.jar";
        copiarArchivo(origen, destino);
    	
    }
    
    public String crearImagenDePrueba(String nombre_juego, String id_juego) throws Exception{
        
        String origen = property+"/Data/install/"+id_juego+".jpeg";
        String destino = property + "/Data/Juegos/"+nombre_juego+"/imagen/"+id_juego+".jpeg";        
        copiarArchivo(origen, destino);
        String[] path = destino.split(property+"/");
        return path[1];       
        
    }
    
    public void copiarArchivo(String origen, String destino) throws Exception{
        try{
            
            Files.copy(new File(origen).toPath(), new File(destino).toPath(), StandardCopyOption.REPLACE_EXISTING);
                        
        }
        catch(IOException e){
                        
            throw new Exception("Error en la copia de archivo: "+e.getMessage());
            
        }
        
    }
    
    public void limpiarJuegos() throws Exception{
        
        File dirJuegos = new File(property+"/Data/Juegos");
        try {
            
            FileUtils.cleanDirectory(dirJuegos);
        
        }
        catch (IOException ex) {
            
            throw new Exception("Error al borrar la carpeta de juegos: "+ex.getMessage());
       
        }
        
    }
    
    public String obtenerBase64(String path) throws Exception{
        
        File imagen = new File(path);
        Archivo a = new Archivo(imagen);
        String img64 = Base64.encodeBytes(a.toBytes());            
        
        return img64;
        
    }
    

    
    
}
